package com.lj.sys.utils;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.lj.common.config.DataScopeHolder;
import com.lj.sys.entity.SysDataScope;
import com.lj.sys.entity.SysUser;
import com.lj.sys.enums.SysDataScopeType;
import com.lj.sys.result.DataScopeResult;
import com.lj.sys.result.LoginUserInfo;
import com.lj.sys.service.SysDataScopeService;
import com.lj.sys.service.SysUserService;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author luojing
 * @since 2025/8/22 18:23
 * 系统用户的相关工具方法
 */
public class SysUserUtils {

    private static final SysDataScopeService sysDataScopeService = SpringUtil.getBean(SysDataScopeService.class);

    private static final SysUserService sysUserService = SpringUtil.getBean(SysUserService.class);

    public static final String USER_INFO_KEY = "userInfo";

    /**
     * @return 获取当前登录的用户信息
     */
    public static LoginUserInfo getUserInfo() {
        return (LoginUserInfo) StpUtil.getSession().get(USER_INFO_KEY);
    }

    /**
     * 为当前<b>登录的用户</b>设置用户信息
     *
     * @param userInfo 当前登录的用户信息
     */
    public static void setUserInfo(LoginUserInfo userInfo) {
        if (StpUtil.isLogin()) {
            StpUtil.getSession().set(USER_INFO_KEY, userInfo);
        }
    }

    /**
     * @return 如果当前时web环境下，获取当前请求的接口url
     */
    private static String getApiUrl() {
        return DataScopeHolder.get();
    }

    /**
     * 获取当前用户针对当前访问的接口拥有的数据权限
     *
     * @return 数据权限信息类
     */
    public static DataScopeResult getDataScope() {
        LoginUserInfo loginUserInfo = getUserInfo();
        List<Long> targetIdList = CollUtil.newArrayList(loginUserInfo.getUserId());
        if (CollUtil.isNotEmpty(loginUserInfo.getRoleIdList())) {
            targetIdList.addAll(loginUserInfo.getRoleIdList());
        }
        DataScopeResult dataScopeResult = new DataScopeResult();
        String apiName = getApiUrl();
        dataScopeResult.setApi(apiName);
        List<SysDataScope> dataScopeList = sysDataScopeService.list(
                sysDataScopeService.lambdaQueryWrapper()
                        .eq(SysDataScope::getUrlPath, apiName)
                        .in(SysDataScope::getTargetId, targetIdList));
        dataScopeResult.setDataScopeList(dataScopeList);
        Set<Long> deptIdSet = new HashSet<>();
        for (SysDataScope sysDataScope : dataScopeList) {
            if (SysDataScopeType.All.equals(sysDataScope.getScope())) {
                // 只要有全部权限就设置为true
                dataScopeResult.setHasAll(true);
            }
            if (SysDataScopeType.Oneself.equals(sysDataScope.getScope())) {
                // 仅可以看到自己的数据
                dataScopeResult.setUserIdList(Collections.singletonList(loginUserInfo.getUserId()));
            }
            if (SysDataScopeType.Department.equals(sysDataScope.getScope())) {
                // 本部门
                deptIdSet.add(loginUserInfo.getDeptId());
            }
            if (SysDataScopeType.DepartmentAndSub.equals(sysDataScope.getScope())) {
                // 所属部门及子部门
                deptIdSet.addAll(loginUserInfo.getDeptIdList());
            }
            if (SysDataScopeType.Custom.equals(sysDataScope.getScope()) &&
                    StrUtil.isNotBlank(sysDataScope.getCustom())) {
                // 自定义部门
                deptIdSet.addAll(StrUtil.split(sysDataScope.getCustom(), StrPool.C_COMMA, -1, true, NumberUtil::parseLong));
            }
        }
        // 如果权限部门id不为空，那么查询这些部门下有那些用户id
        if (CollUtil.isNotEmpty(deptIdSet)) {
            dataScopeResult.setDeptIdSet(deptIdSet);
            List<Long> userIdList = sysUserService.listObjs(sysUserService.lambdaQueryWrapper()
                    .select(SysUser::getId)
                    .in(SysUser::getDeptId, deptIdSet), o -> (Long) o);
            if (CollUtil.isNotEmpty(userIdList)) {
                dataScopeResult.setUserIdList(userIdList);
            }
        }
        return dataScopeResult;
    }
}
